#pragma once

#include <Windows.h>

namespace collections
{

	/* Indirection 0 chain, allow fast deleting of a item in the middle of the chain
	you got a pointer on */
	class Ind0Chain;

	class Ind0ChainMbr
	{
	private:
		Ind0Chain* _mOwner;
		Ind0ChainMbr* _mNext;
		Ind0ChainMbr* _mPrev;
	public:
		Ind0ChainMbr()                        {ZeroMemory(this, sizeof(*this));}
		virtual ~Ind0ChainMbr()               {if (_mOwner) _pop();}
		void _pop(); //removes this item from the owner chain
		inline Ind0ChainMbr* _getNext()       {return _mNext;}
		inline Ind0ChainMbr* _getPrev()       {return _mNext;}
		inline Ind0Chain*    _getOwner()      {return _mOwner;}
		inline void _setNext(Ind0ChainMbr* n) {_mNext = n;}
		inline void _setPrev(Ind0ChainMbr* p) {_mPrev = p;}
		inline void _setOwner(Ind0Chain* o)   {_mOwner = o;}
	};

	class Ind0Chain
	{
	public:
		class iterator
		{
			Ind0ChainMbr* mObj;
		public:
			iterator(Ind0ChainMbr* obj)         {mObj = obj;}
			inline Ind0ChainMbr* operator*()    {return mObj;}
			inline Ind0ChainMbr* operator->()   {return mObj;}
			inline void operator++()            {mObj = mObj->_getNext();}
			inline void operator++(int)         {mObj = mObj->_getNext();}
			inline bool operator==(iterator it) {return mObj == *it;}
			inline bool operator!=(iterator it) {return mObj != *it;}
		};

	private:
		Ind0ChainMbr* mFirst;
		Ind0ChainMbr* mLast;
		int mCount;
		bool mBorrow;
	public:
		//if borrow : the contained elements are not deleted with the chain
		Ind0Chain(bool borrow) {mFirst = NULL; mLast = NULL; mCount = 0; mBorrow = borrow;}
		~Ind0Chain();
		void push_front(Ind0ChainMbr*);
		inline int size()       {return mCount;}
		inline iterator begin() {return iterator(mFirst);}
		inline iterator end()   {return iterator(NULL);}
		inline void _setFirst(Ind0ChainMbr* f) {mFirst = f;}
		inline void _setLast(Ind0ChainMbr* l)  {mLast = l;}
		inline void _decSize()                 {mCount--;}
	};

}